﻿/**
 * Licensed under the MIT License
 *
 * Copyright (c) 2010 Laurent Berthelot
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package marcel.display.draw.props
{
	import flash.display.GradientType;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import marcel.utils.MathUtils;
	
	
	/**
	* Fill properties used by DrawManager to draw vector shape.
	* @author Laurent Berthelot
	*/
	public class FillProps
	{
		//--------------------------------------------------------------------------
		//
		//  Public vars
		//
		//--------------------------------------------------------------------------
		/**
		 * The hexadecimal color value used for unicolored fill.
		 */
		public var color : Number;
		/**
		 * The alpha value of the color for unicolored fill.
		 */
		public var alpha : Number;
		/**
		 * Indicates if the fill is a gradient fill (true) or a simple, unicolored fill (false).
		 */
		public var gradient : Boolean = false;
		/**
		 * Array of RGB hexadecimal color values used for gradient fill.
		 */
		public var fillType : String;
		/**
		 * Array of RGB hexadecimal color values used for gradient fill.
		 */
		public var gradientColor : Array;
		/**
		 * Array of alpha values of the colors (gradientColor) used for gradient fill.
		 */
		public var gradientAlpha : Array;
		/**
		 * Array of color distribution ratios used for gradient fill.
		 */
		public var gradientDistrib : Array;
		/**
		 * The ratation value of the gradient fill.
		 */
		public var rotation : Number;
		
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		/**
		 * Constructs a new FillProps instance
		 * @param	color		Array of hexadecimal colors for gradient fill or hexadecimal color for unicolored fill.
		 * @param	alpha		Array of alphas for gradient fill or alpha of color for unicolored fill.
		 * @param	distrib		Color distribution in percentage (Only for gradient fill mode).
		 * @param	fillType	Gradient fill type (GradientType.FILL_TYPE_RADIAL or GradientType.FILL_TYPE_LINEAR - Only for gradient fill mode).
		 * @param	rotation	Gradient rotation in degrees (Only for gradient fill mode).
		 */
		public function FillProps(color: Object = 0, alpha: Object = 1, distrib : Array = null, fillType : String = null, rotation : Number = 0) {
			var nbColor:Number = 1;
			if (color is Array) nbColor = Math.max(nbColor, color.length);
			if (alpha != null && alpha is Array) nbColor = Math.max(nbColor, alpha.length);
			if (distrib != null) nbColor = Math.max(nbColor, distrib.length);
			gradient = nbColor > 1;
			if (!gradient) {
				this.color = (color !== null) ? Number((color is Array)? color[0] : color ) : 0;
				this.alpha = (alpha !== null) ? Number(alpha) : 1;
				return;
			}
			var _aColor:Array = new Array();
			var _aAlpha:Array = new Array();
			var _aDistrib:Array = new Array();
			var i:int;
			// Colors
			if (color is Array) {
				_aColor = color.concat();
				while (_aColor.length < nbColor) _aColor.push(_aColor[_aColor.length - 1]);
			} else {
				for (i = 0; i < nbColor; i++) _aColor.push(color);
			}
			// Alpha
			if (alpha is Array) {
				_aAlpha = alpha.concat();
				while (_aAlpha.length < nbColor) _aAlpha.push(_aAlpha[_aAlpha.length]);
			} else {
				for (i = 0; i < nbColor; i++) _aAlpha.push(alpha);
			}
			// Distrib
			if (distrib != null) {
				_aDistrib = distrib.concat();
				if (_aDistrib.length < nbColor) {
					var lastDistrib:Number = distrib[distrib.length - 1];
					var gap:Number = (100 - lastDistrib) / (nbColor - _aDistrib.length);
					var k:Number = 1;
					while (_aDistrib.length < nbColor) {
						_aDistrib.push(lastDistrib + gap * k);
						k++;
					}
				}
			} else {
				_aDistrib.push(0);
				for (i = 1; i < nbColor - 1; i++) _aDistrib.push(100 / (nbColor-1) * i );
				_aDistrib.push(100);
			}
			gradientColor = _aColor;
			gradientAlpha = _aAlpha;
			gradientDistrib = new Array();
			for (i = 0; i < nbColor; i++ ) gradientDistrib.push( _aDistrib[ i ] * ( 0xFF ) / 100 );
			this.fillType = ( fillType != GradientType.RADIAL && fillType != GradientType.LINEAR )? GradientType.LINEAR : fillType;
			this.rotation = MathUtils.degreeToRadian( isNaN( rotation ) ? 0 : rotation);
		}
		
		//--------------------------------------------------------------------------
		//
		//  Public methods
		//
		//--------------------------------------------------------------------------
		/**
		 * Create a transformation matrix for gradient fill
		 * @return	flash.geom.Matrix: The matrix used by MovieClip.beginGradientFill() method.
		 */
		public function getGradientMatrix(rec:Rectangle, rotation:Number = 0) : Matrix {
			var oMatrix : Matrix = new Matrix();
			oMatrix.createGradientBox( rec.width, rec.height, rotation, rec.x, rec.y);
			return oMatrix;
		}
		
	}
}